use std::fmt::{Display, Formatter};

/// 获取类型名
fn type_of<T>(_: T) -> &'static str {
    std::any::type_name::<T>()
}

fn type_of2<T>(val: &T) -> &'static str {
    std::any::type_name_of_val(val)
}

#[derive(Debug)]
struct User {
    name: String,
    age: u8,
    email: String,
}

impl User {
    fn new() -> User {
        User {
            name: String::from("leehuajun"),
            age: 108,
            email: "leehuajun@qq.com".to_string(),
        }
    }

    fn say(&self) {
        println!(
            "hi,my name is {},my age is {},my email:{}",
            self.name, self.age, self.email
        )
    }
}

impl Display for User {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        let message = format!(
            "用户:user.name:{},user.age:{},user.email:{}",
            self.name, self.age, self.email
        );
        // 使用{},  打印: 用户:user.name:leehuajun,user.age:108,user.email:leehuajun@qq.com
        // 使用{:?},打印："用户:user.name:leehuajun,user.age:108,user.email:leehuajun@qq.com"，
        // 就是多了前后的双引号
        write!(f, "{:?}", message)
    }
}

fn main() {
    let food = "清蒸螃蟹";
    let price = 366;
    let checked = true;

    // println!("food is {}", food);
    // println!("price is {}", price);
    // println!("checked is {}", checked);

    println!("food type_name is {}", type_of(food));
    println!("price type_name is {}", type_of(price));
    println!("checked type_name is {}", type_of(checked));

    println!("food type_name is {}", type_of2(&food));
    println!(
        "checked 的类型名称是：{}",
        std::any::type_name_of_val(&checked)
    );

    let u = User::new();
    println!("u 的类型名称是：{}", std::any::type_name_of_val(&u));
    println!("u:{:?}", u);
    u.say();
    println!("{}", u)
}
